﻿using System;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Runtime.InteropServices;
using woaC2.Common;
using woaC2.Common.Const;
using woaC2.LogicLib.GlobalShare;

namespace woaC2.SocketApp
{
    class Program
    {

        #region Kernel32
        // A simple class that exposes two static Win32 functions.
        // One is a delegate type and the other is an enumerated type.
        public class MyWin32
        {
            // Declare the SetConsoleCtrlHandler function 
            // as external and receiving a delegate.   
            [DllImport("Kernel32")]
            public static extern Boolean SetConsoleCtrlHandler(HandlerRoutine Handler,
                Boolean Add);

            // A delegate type to be used as the handler routine 
            // for SetConsoleCtrlHandler.
            public delegate Boolean HandlerRoutine(CtrlTypes CtrlType);

            // An enumerated type for the control messages 
            // sent to the handler routine.
            public enum CtrlTypes
            {
                CTRL_C_EVENT = 0,
                CTRL_BREAK_EVENT,
                CTRL_CLOSE_EVENT,
                CTRL_LOGOFF_EVENT = 5,
                CTRL_SHUTDOWN_EVENT
            }
        }
        #endregion
        
        /// <summary>
        /// Nhận lệnh điều khiển APPSever
        /// </summary>
        static string command = null;
        
        /// <summary>
        /// Lock
        /// </summary>
        static object syncObj = new object();

        /// <summary>
        /// Khởi tạo các tham số sever
        /// </summary>
        static void StartApp()
        {   
            // Use interop to set a console control handler.
            MyWin32.HandlerRoutine hr = new MyWin32.HandlerRoutine(StopApp);
            MyWin32.SetConsoleCtrlHandler(hr, true);

            Console.ForegroundColor = ConsoleColor.DarkGray;
            Console.InputEncoding = System.Text.Encoding.UTF8;
            Console.OutputEncoding = System.Text.Encoding.UTF8;

            XDocument serverAppParam = XDocument.Load(Directory.GetCurrentDirectory() + @"\Setting.xml");

            #region Cấu hình Socket
            var sfSocket = serverAppParam.Descendants("Socket").First();
            AssetsGS.instance.SocketConfig_Port = Convert.ToUInt16(sfSocket.Attribute("Port").Value);
            AssetsGS.instance.SocketConfig_MaxxCCU = Convert.ToUInt16(sfSocket.Attribute("MaxCCU").Value);
            #endregion 
            
            #region Cấu hình Database
            var sfDatabase = serverAppParam.Descendants("Database").First();
            AssetsGS.instance.DatabaseConfig_ConnectStr = Convert.ToString(sfDatabase.Attribute("ConnectStr").Value);
            #endregion 

            #region Cấu hình cho client
            var sfClient = serverAppParam.Descendants("Client").First();
            AssetsGS.instance.ClientConfig_TimeOut = Convert.ToInt32(sfClient.Attribute("TimeOut").Value);
            #endregion 

            TimeLineGS.instance.Start();

        }
        
        /// <summary>
        /// Sự Kiện dừng Sever
        /// </summary>
        /// <param name="ctrlType"></param>
        /// <returns></returns>
        static Boolean StopApp(MyWin32.CtrlTypes ctrlType)
        {
            if (ctrlType == MyWin32.CtrlTypes.CTRL_BREAK_EVENT ||
                ctrlType == MyWin32.CtrlTypes.CTRL_C_EVENT ||
                ctrlType == MyWin32.CtrlTypes.CTRL_CLOSE_EVENT ||
                ctrlType == MyWin32.CtrlTypes.CTRL_LOGOFF_EVENT ||
                ctrlType == MyWin32.CtrlTypes.CTRL_SHUTDOWN_EVENT)
            {
                // Xử lý đóng ứng dụng
                Console.Write("Waiting for Exit...");
            }
            return true;
        }

        /// <summary>
        /// Main Method
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            StartApp();
            while (true)
            {
                Console.Write(">>");
                command = Console.ReadLine();
                ProcessCommand();
            }
        }
        
        /// <summary>
        /// Chia lệnh đầu vào
        /// </summary>
        /// <returns></returns>
        static string[] SplitCommand()
        {
            return (command != null) ? command.Split(' ') : null;
        }

        /// <summary>
        /// Xử lý các lệnh điều khiển Server
        /// </summary>
        static void ProcessCommand()
        {
            string[] paramCmd = SplitCommand();

            if (paramCmd == null) return;

            command = null;
            try
            {
                switch (paramCmd[0])
                {
                    case ApConst.SocketApp.CMD_START:
                        CommandCtrl.StartCommand();
                        break;
                    case ApConst.SocketApp.CMD_STOP:
                        CommandCtrl.StopCommand();
                        break;
                    case ApConst.SocketApp.CMD_MAXCCU:
                        CommandCtrl.MaxCCUCommand(paramCmd[1]);
                        break;
                    case ApConst.SocketApp.CMD_CCU:
                        CommandCtrl.CCUCommand();
                        break;
                    case ApConst.SocketApp.CMD_PORT:
                        CommandCtrl.PORTCommand();
                        break;
                   
                    default:
                        break;
                }
            }
            catch (Exception e)
            {
                Log.WriteOnScreen1("[Error]: " + e.Message);
            }

        }
    }
}
